package com.mvc.core.utils;

import java.math.BigDecimal;

/**
 * 
 * 四则运算,只接受double类型，其他类型强转也会有精度问题，可以用valueOf字符串的方式转换为double， 比如
 * Double.valueOf(12f+"")解决精度问题;
 *
 * @author lt
 * @version 2017年11月30日上午9:15:02
 */
public class ArithUtils {

	/**
	 * 保留小数位
	 */
	private static final int DEF_DIV_SCALE = 4;

	/**
	 * 结果值
	 */
	private BigDecimal currNum = null;

	private ArithUtils(BigDecimal dcimal) {
		currNum = dcimal;
	}

	/**
	 * 初始化运算对象
	 * 
	 * @param v1
	 * @return
	 */
	public static ArithUtils init(Double v1) {
		BigDecimal b1 = BigDecimal.valueOf(v1);
		return new ArithUtils(b1);
	}

	/**
	 * 两数直接相加
	 * 
	 * @param v1
	 * @param v2
	 * @return
	 */
	public static ArithUtils add(Double v1, Double v2) {
		BigDecimal b1 = BigDecimal.valueOf(v1);
		BigDecimal b2 = BigDecimal.valueOf(v2);
		return new ArithUtils(b1.add(b2));
	}

	/**
	 * 运算结果后，跟着相加
	 * 
	 * @param v1
	 * @return
	 */
	public ArithUtils add(Double v1) {
		BigDecimal b1 = BigDecimal.valueOf(v1);
		this.currNum = currNum.add(b1);
		return this;
	}

	/**
	 * 两数直接相减
	 * 
	 * @param v1 减数
	 * @param v2 被减数
	 * @return
	 */
	public static ArithUtils sub(Double v1, Double v2) {
		BigDecimal b1 = BigDecimal.valueOf(v1);
		BigDecimal b2 = BigDecimal.valueOf(v2);
		return new ArithUtils(b1.subtract(b2));
	}

	/**
	 * 运算结果后，跟着相减
	 * 
	 * @param v1 减数
	 * @param v2 被减数
	 * @return
	 */
	public ArithUtils sub(Double v1) {
		BigDecimal b1 = BigDecimal.valueOf(v1);
		this.currNum = currNum.subtract(b1);
		return this;
	}

	/**
	 * 两数直接相乘
	 * 
	 * @param v1
	 * @param v2
	 * @return
	 */
	public static ArithUtils mul(Double v1, Double v2) {
		BigDecimal b1 = BigDecimal.valueOf(v1);
		BigDecimal b2 = BigDecimal.valueOf(v2);
		return new ArithUtils(b1.multiply(b2));
	}

	/**
	 * 运算结果后，跟着相乘
	 * 
	 * @param v1
	 * @param v2
	 * @return
	 */
	public ArithUtils mul(Double v1) {
		BigDecimal b1 = BigDecimal.valueOf(v1);
		this.currNum = currNum.multiply(b1);
		return this;
	}

	/**
	 * 两数直接相除
	 * 
	 * @param v1 除数
	 * @param v2 被除数
	 * @return
	 */
	public static ArithUtils div(Double v1, Double v2) {
		BigDecimal b1 = BigDecimal.valueOf(v1);
		BigDecimal b2 = BigDecimal.valueOf(v2);
		return new ArithUtils(b1.divide(b2, DEF_DIV_SCALE, BigDecimal.ROUND_HALF_UP));
	}

	/**
	 * 运算结果后，跟着相除
	 * 
	 * @param v1 除数
	 * @param v2 被除数
	 * @return
	 */
	public ArithUtils div(Double v1) {
		BigDecimal b1 = BigDecimal.valueOf(v1);
		this.currNum = currNum.divide(b1, DEF_DIV_SCALE, BigDecimal.ROUND_HALF_UP);
		return this;
	}

	/**
	 * 返回结果
	 * 
	 * @return
	 */
	public Double doubleValue() {
		return currNum.setScale(DEF_DIV_SCALE, BigDecimal.ROUND_DOWN).doubleValue();
	}

	/**
	 * 返回结果
	 * 
	 * @return
	 */
	public long longValue() {
		return currNum.setScale(DEF_DIV_SCALE, BigDecimal.ROUND_DOWN).longValue();
	}

	/**
	 * 返回结果
	 * 
	 * @return
	 */
	public int intValue() {
		return currNum.setScale(DEF_DIV_SCALE, BigDecimal.ROUND_DOWN).intValue();
	}

	/**
	 * 返回结果
	 * 
	 * @return
	 */
	public float floatValue() {
		return currNum.setScale(DEF_DIV_SCALE, BigDecimal.ROUND_DOWN).floatValue();
	}

	/**
	 * 返回结果
	 * 
	 * @return
	 */
	public short shortValue() {
		return currNum.setScale(DEF_DIV_SCALE, BigDecimal.ROUND_DOWN).shortValue();
	}

	/**
	 * 返回结果
	 * 
	 * @return
	 */
	public byte byteValue() {
		return currNum.setScale(DEF_DIV_SCALE, BigDecimal.ROUND_DOWN).byteValue();
	}

}
